//
//  ZZCWKURLRequestParseManager.swift
//  ewgShop
//
//  Created by zzc on 2019/8/5.
//  Copyright © 2019 zzc. All rights reserved.
//

import UIKit
import WebKit

class ZZCWKURLRequestParseManager: NSObject {
    
    typealias argumentHandler = (_ path : String) -> ();
    
    weak var viewController : ZZCCordovaBaseWebViewVC?;
    
    let schemeParser = ZZCURLSchemeParser.init();
    let hostParser = ZZCURLHostParser.init();
    let queryParser = ZZCURLQueryParser.init();
    

    func actionForWebviewWithRequestAndNavigationType(webview : WKWebView , request : NSURLRequest , navigationType : WKNavigationType) -> ZZCWebViewRequestAction {
        
        var requestAction = ZZCWebViewRequestAction.Other
        
        // 1. URL中的分析处理优先级最高
        requestAction = actionForParsingWebViewRequest(request: request)
        if requestAction != ZZCWebViewRequestAction.Other{
            return requestAction
        }
        
        switch navigationType {
        case .linkActivated:
            requestAction = actionForLinkActivatedWebViewWithRequest(webView: webview, request: request)
            break;
        case .formSubmitted :
            requestAction = actionForSubmittedWebViewWithRequest(webView: webview, request: request)
            break;
        case .backForward:
            requestAction = actionForLinkBackForwardWebViewWithRequest(webView: webview, request: request)
            break;
        case .reload:
            requestAction = actionForLinkReloaddWebViewWithRequest(webView: webview, request: request)
            break;
        case .formResubmitted:
            requestAction = actionForLinkFormResubmittedWebViewWithRequest(webView: webview, request: request)
            break;
        default:
            requestAction = actionForLinkOtherWebViewWithRequest(webView: webview, request: request)
        }
        
        return requestAction;
    }
    
    func actionForParsingWebViewRequest(request:NSURLRequest) -> ZZCWebViewRequestAction {
        var requestAction = ZZCWebViewRequestAction.Other
        if (request.url!.scheme! as NSString).isEqual(to: CUSTOM_SCHEME) {
            requestAction = ZZCWebViewRequestAction.Custom
        }else if(shouldThwartOpenOtherAppForRequestURL(requestURL: request.url! as NSURL) == false){
            requestAction = ZZCWebViewRequestAction.OpenOtherApp
        }else if(shouldOpenNewWebViewForRequestURL(requestURL: request.url as NSURL?)){
            requestAction = ZZCWebViewRequestAction.PushNewWebView
        }else if(shouldOpenSelfWebViewForRequestURL(requestURL: request.url as NSURL?)){
            requestAction = ZZCWebViewRequestAction.SelfOpen
        }
        return requestAction;
    }
    
    func shouldThwartOpenOtherAppForRequestURL(requestURL: NSURL) -> Bool {
        var shouldThwartOpenOtherApp = false
        if self.schemeParser.whiteListHasScheme(scheme: requestURL.scheme!) ||
            self.hostParser.whiteListHasHost(host: requestURL.host!){
            shouldThwartOpenOtherApp = true;
        }
        if self.hostParser.blackListHasHost(host: requestURL.host!){
            shouldThwartOpenOtherApp = false;
        }
        return shouldThwartOpenOtherApp;
    }
    
    func shouldOpenNewWebViewForRequestURL(requestURL:NSURL?) -> Bool {
        var shouldOpenNewWebView = false
        if self.queryParser .queryOfRequestURLHasArgument(requestURL: requestURL!, argument: "appopenpage") {
            shouldOpenNewWebView = true;
        }
        return shouldOpenNewWebView
        
    }
    
    func shouldOpenSelfWebViewForRequestURL(requestURL:NSURL?) -> Bool {
        var shouldOpenSelfWebView = false
        if self.queryParser.queryOfRequestURLHasArgument(requestURL: requestURL!, argument: "selfopenpage") {
            shouldOpenSelfWebView = true;
        }
        return shouldOpenSelfWebView
    }
    
/////////
    func actionForLinkActivatedWebViewWithRequest(webView:WKWebView , request : NSURLRequest) -> ZZCWebViewRequestAction {
        var requestAction = ZZCWebViewRequestAction.PushNewWebView
        
        if shouldOpenSelfWebViewForRequestURL(requestURL: request.url as NSURL?) {
            requestAction = ZZCWebViewRequestAction.SelfOpen
        }
        
        if shouldOpenNewWebViewForRequestURL(requestURL: request.url as NSURL?) {
            requestAction = ZZCWebViewRequestAction.PushNewWebView
        }
        return requestAction;
    }
    
    func actionForSubmittedWebViewWithRequest(webView:WKWebView , request : NSURLRequest) -> ZZCWebViewRequestAction {
        return ZZCWebViewRequestAction.Other
    }
    
    func actionForLinkBackForwardWebViewWithRequest(webView:WKWebView , request : NSURLRequest) -> ZZCWebViewRequestAction {
        return ZZCWebViewRequestAction.Other
    }
    
    func actionForLinkReloaddWebViewWithRequest(webView:WKWebView , request : NSURLRequest) -> ZZCWebViewRequestAction  {
        return ZZCWebViewRequestAction.Other
    }
    
    func actionForLinkFormResubmittedWebViewWithRequest(webView:WKWebView , request : NSURLRequest) -> ZZCWebViewRequestAction {
        return ZZCWebViewRequestAction.Other
    }
    
    func actionForLinkOtherWebViewWithRequest(webView:WKWebView , request : NSURLRequest) -> ZZCWebViewRequestAction  {
        if (request.url!.absoluteString as NSString).range(of: "base64").length > 0 {
            return ZZCWebViewRequestAction.Other
        }
        
        if (((webView.url!.scheme! as NSString).isEqual(to: (request.url!.scheme!)) && (webView.url!.path as NSString).isEqual(to: request.url!.path)) && ((webView.url?.query != nil && request.url?.query != nil && (webView.url!.query! as NSString).isEqual(to: request.url!.query!)) || (webView.url?.query == nil && request.url?.query == nil && (webView.url!.fragment! as NSString).isEqual(to: request.url!.fragment!) == false))){
            return ZZCWebViewRequestAction.Other;
        }
        
        var requestAction = ZZCWebViewRequestAction.PushNewWebView
        if shouldOpenSelfWebViewForRequestURL(requestURL: request.url as NSURL?){
            requestAction = ZZCWebViewRequestAction.SelfOpen
        }
        
        if shouldOpenNewWebViewForRequestURL(requestURL: request.url as NSURL?) {
            requestAction = ZZCWebViewRequestAction.PushNewWebView
        }
        return requestAction;
    }
    
    func navigationPolicyForURL(url:NSURL?) -> NSInteger {
        if url  == nil{
            return 0;
        }
        var navigationActionPolicy = -1;
        if self.schemeParser.blackListHasScheme(scheme: (url?.scheme)!){
            navigationActionPolicy = 0
        }
        if self.schemeParser.whiteListHasScheme(scheme: (url?.scheme)!){
            navigationActionPolicy = 1
        }
        if self.hostParser.blackListHasHost(host: (url?.host)!) {
            navigationActionPolicy = 0;
        }
        if self.hostParser.whiteListHasHost(host: (url?.host)!) {
            navigationActionPolicy = 1;
        }
        return navigationActionPolicy as NSInteger;
    }
    
    func handleRequestURL(requestURL:NSURL?) {
        self.queryParser.handleURL(url: requestURL)
    }
    
///// schemeParser method
    func registerToWhiteListWithScheme(scheme : String)  {
        self.schemeParser.registerToWhiteListWithScheme(scheme: scheme)
    }
    
    func registerToBlackListWithScheme(scheme : String) {
        self.schemeParser.registerToBlackListWithScheme(scheme: scheme)
    }
    
////// hostParser method
    func registerToWhiteListWithHost(host : String){
        self.hostParser.registerToWhiteListWithHost(host: host)
    }
    
    func registerToBlackListWithHost(host : String){
        self.hostParser.registerToBlackListWithHost(host: host)
    }
    
    
    func registerQueryArgumentwithHandler(argument:String , handler : @escaping argumentHandler) {
        self.queryParser.registerQueryArgumentWithHandler(argument: argument, handler: handler)
    }
    
    func registerQueryArgumentWithNonexistentHandler(argument:String ,handle:@escaping argumentHandler){
        self.queryParser.registerQueryArgumentWithNonexistentHandler(argument: argument, handler: handle)
    }
    
    
    ////// public scheme param handle
    
    /// 处理ZZCAppArg中的NoGoBackBtn参数，有此参数时，应隐藏返回按钮
    ///
    /// - Parameter handle: 自定义处理逻辑
    func registerHideBackButtonArgumentWithHandler(handle :@escaping argumentHandler){
        self.queryParser.registerQueryArgumentWithHandler(argument: "nogobackbtn", handler: handle)
    }
    
    func registerHideHomeButtonArgumentWithHandler(handle:@escaping argumentHandler){
        self.queryParser.registerQueryArgumentWithHandler(argument: "nogohomebtn", handler: handle)
    }
    
    func registerHideNavigationBarArgumentWithHandler(handle: @escaping argumentHandler) {
        self.queryParser.registerQueryArgumentWithHandler(argument: "hidetopbar=true,topbar_remove", handler: handle)
    }
    
    func registerTransparentizeNavigationBarArgumentWithHandler(handle: @escaping argumentHandler){
        self.queryParser.registerQueryArgumentWithHandler(argument: "topbar_hidden", handler: handle)
    }
    
    func registerDefaultNavigationBarArgumentWithHandler(handle : @escaping argumentHandler){
        self.queryParser.registerQueryArgumentWithHandler(argument: "topbar_deafult", handler: handle)
    }
    
    func registerWebViewStartArgumentWithHandler(handle : @escaping argumentHandler){
        self.queryParser.registerQueryArgumentWithHandler(argument: "webviewstart_zero,webviewstart_statusbar,webviewstart_topbar", handler: handle)
    }
    
    func registerForbidWebViewToScrollArgumentWithHandler(handle:@escaping argumentHandler){
        self.queryParser.registerQueryArgumentWithHandler(argument: "forbiddenscroll=true", handler: handle)
    }
    
    func registerForbidWebViewToBouncesArgumentWithHandler(handle:@escaping argumentHandler){
        self.queryParser.registerQueryArgumentWithHandler(argument:"nowebviewslide", handler:handle)
    }
}
